﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using YArchitech.Revit;

namespace Model
{
	public class PointSort : XYZ
	{
		public PointSort(XYZ ptPos, double dParam) : base(ptPos.X, ptPos.Y, ptPos.Z)
		{
			this.m_dParam = dParam;
			this.m_lstConduits = new List<Conduit>();
		}

		public double Param
		{
			get
			{
				return this.m_dParam;
			}
		}

		public List<Conduit> ListConduits
		{
			get
			{
				return this.m_lstConduits;
			}
		}

		public FamilyInstance CreateFitting(Document doc, ConduitType type)
		{
			FamilyInstance familyInstance = null;
			if (this.m_lstConduits.Count > 1)
			{
				SubTransaction subTransaction = new SubTransaction(doc);
				try
				{
					subTransaction.Start();
					switch (this.m_lstConduits.Count)
					{
					case 2:
					{
						Connector conduitConn = this.GetConduitConn(this.m_lstConduits[0]);
						Connector conduitConn2 = this.GetConduitConn(this.m_lstConduits[1]);
						if (conduitConn != null && conduitConn2 != null)
						{
							familyInstance = doc.Create.NewElbowFitting(conduitConn, conduitConn2);
						}
						break;
					}
					case 3:
					{
						Connector conduitConn3 = this.GetConduitConn(this.m_lstConduits[0]);
						Connector conduitConn4 = this.GetConduitConn(this.m_lstConduits[1]);
						Connector conduitConn5 = this.GetConduitConn(this.m_lstConduits[2]);
						if (conduitConn3 != null && conduitConn4 != null && conduitConn5 != null)
						{
							Connector connector = null;
							Connector connector2 = null;
							Connector connector3 = null;
							if (conduitConn3.CoordinateSystem.BasisZ.IsAlmostEqualTo(-conduitConn4.CoordinateSystem.BasisZ))
							{
								connector = conduitConn3;
								connector2 = conduitConn4;
								connector3 = conduitConn5;
							}
							else if (conduitConn3.CoordinateSystem.BasisZ.IsAlmostEqualTo(-conduitConn5.CoordinateSystem.BasisZ))
							{
								connector = conduitConn3;
								connector2 = conduitConn5;
								connector3 = conduitConn4;
							}
							else
							{
								connector = conduitConn4;
								connector2 = conduitConn5;
								connector3 = conduitConn3;
							}
							bool flag = false;
							if (connector3.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || connector3.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ))
							{
								flag = true;
							}
							if (!flag && connector3.CoordinateSystem.BasisZ.CrossProduct(XYZ.BasisZ).Normalize().IsAlmostEqualTo(connector2.CoordinateSystem.BasisZ))
							{
								Connector connector4 = connector;
								connector = connector2;
								connector2 = connector4;
							}
							ElementId elementId = type.get_Parameter(BuiltInParameter.RBS_CURVETYPE_DEFAULT_TEE_PARAM).AsElementId();
							FamilySymbol familySymbol = doc.GetElement(elementId) as FamilySymbol;
							UnifiedModified.ActivateFamilySymbol(familySymbol);
							familyInstance = doc.Create.NewFamilyInstance(this, familySymbol, 0);
							ConnectorSet connectors = familyInstance.MEPModel.ConnectorManager.Connectors;
							Connector connector5 = null;
							Connector connector6 = null;
							Connector connector7 = null;
							foreach (object obj in connectors)
							{
								Connector connector8 = (Connector)obj;
								if (flag && (connector8.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || connector8.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ)))
								{
									connector7 = connector8;
								}
								else if (!flag && (connector8.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisY) || connector8.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisY)))
								{
									connector7 = connector8;
								}
								else if (connector8.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisX))
								{
									connector6 = connector8;
								}
								else if (connector8.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisX))
								{
									connector5 = connector8;
								}
							}
							if (connector5 != null && connector6 != null && connector7 != null)
							{
								double num;
								if (flag)
								{
									num = connector5.CoordinateSystem.BasisZ.AngleOnPlaneTo(-connector.CoordinateSystem.BasisZ, XYZ.BasisZ);
								}
								else
								{
									num = connector7.CoordinateSystem.BasisZ.AngleOnPlaneTo(-connector3.CoordinateSystem.BasisZ, XYZ.BasisZ);
								}
								Line line = Line.CreateBound(this, this + XYZ.BasisZ * 10.0);
								ElementTransformUtils.RotateElement(doc, familyInstance.Id, line, num);
								connector.Origin = connector5.Origin;
								connector2.Origin = connector6.Origin;
								connector3.Origin = connector7.Origin;
								connector.ConnectTo(connector5);
								connector2.ConnectTo(connector6);
								connector3.ConnectTo(connector7);
							}
							else
							{
								doc.Delete(familyInstance.Id);
							}
						}
						break;
					}
					case 4:
						familyInstance = this.CreateXOYCrossFitting(this.m_lstConduits[0], this.m_lstConduits[1], this.m_lstConduits[2], this.m_lstConduits[3], type, doc);
						break;
					case 5:
					{
						Connector connector9 = null;
						foreach (Conduit conduit in this.m_lstConduits)
						{
							Connector conduitConn6 = this.GetConduitConn(conduit);
							if (conduitConn6 != null && (conduitConn6.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || conduitConn6.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ)))
							{
								connector9 = conduitConn6;
								Conduit item = conduit;
								this.m_lstConduits.Remove(item);
								break;
							}
						}
						if (connector9 != null)
						{
							familyInstance = this.CreateXOYCrossFitting(this.m_lstConduits[0], this.m_lstConduits[1], this.m_lstConduits[2], this.m_lstConduits[3], type, doc);
							if (familyInstance != null)
							{
								foreach (object obj2 in familyInstance.MEPModel.ConnectorManager.Connectors)
								{
									Connector connector10 = (Connector)obj2;
									if (connector10.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || connector10.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ))
									{
										connector9.Origin = connector10.Origin;
										connector9.ConnectTo(connector10);
										break;
									}
								}
							}
						}
						break;
					}
					}
					subTransaction.Commit();
				}
				catch
				{
					subTransaction.RollBack();
					return null;
				}
				return familyInstance;
			}
			return familyInstance;
		}

		private Connector GetConduitConn(Conduit elemConduit)
		{
			if (elemConduit != null)
			{
				ConnectorSetIterator connectorSetIterator = elemConduit.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector = obj as Connector;
					if (connector != null && connector.Origin.IsAlmostEqualTo(this))
					{
						return connector;
					}
				}
			}
			return null;
		}

		private FamilyInstance CreateXOYCrossFitting(Conduit con0, Conduit con1, Conduit con2, Conduit con3, ConduitType type, Document doc)
		{
			FamilyInstance familyInstance = null;
			Connector conduitConn = this.GetConduitConn(con0);
			Connector conduitConn2 = this.GetConduitConn(con1);
			Connector conduitConn3 = this.GetConduitConn(con2);
			Connector conduitConn4 = this.GetConduitConn(con3);
			Connector connector = conduitConn3;
			Connector connector2 = conduitConn4;
			Connector connector3 = null;
			Connector connector4 = null;
			bool flag = false;
			if (conduitConn.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || conduitConn.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ))
			{
				flag = true;
				connector3 = conduitConn2;
				connector4 = conduitConn;
			}
			else if (conduitConn2.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || conduitConn2.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ))
			{
				flag = true;
				connector3 = conduitConn;
				connector4 = conduitConn2;
			}
			if (!flag)
			{
				if (connector.CoordinateSystem.BasisZ.CrossProduct(XYZ.BasisZ).Normalize().IsAlmostEqualTo(conduitConn.CoordinateSystem.BasisZ))
				{
					connector3 = conduitConn;
					connector4 = conduitConn2;
				}
				else
				{
					connector3 = conduitConn2;
					connector4 = conduitConn;
				}
			}
			if (connector != null && connector2 != null && connector3 != null && connector4 != null)
			{
                BuiltInParameter builtInParameter = flag ? (BuiltInParameter)(-1114111) : (BuiltInParameter)(-1114112);
				ElementId elementId = type.get_Parameter(builtInParameter).AsElementId();
				FamilySymbol familySymbol = doc.GetElement(elementId) as FamilySymbol;
				UnifiedModified.ActivateFamilySymbol(familySymbol);
				familyInstance = doc.Create.NewFamilyInstance(this, familySymbol, 0);
				ConnectorSet connectors = familyInstance.MEPModel.ConnectorManager.Connectors;
				Connector connector5 = null;
				Connector connector6 = null;
				Connector connector7 = null;
				Connector connector8 = null;
				foreach (object obj in connectors)
				{
					Connector connector9 = (Connector)obj;
					if (flag && (connector9.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ) || connector9.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisZ)))
					{
						connector8 = connector9;
					}
					else if (!flag && connector9.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisY))
					{
						connector7 = connector9;
					}
					else if (!flag && connector9.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisY))
					{
						connector8 = connector9;
					}
					else if (connector9.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisX))
					{
						connector6 = connector9;
					}
					else if (connector9.CoordinateSystem.BasisZ.IsAlmostEqualTo(-XYZ.BasisX))
					{
						connector5 = connector9;
					}
				}
				if (connector5 != null && connector6 != null && connector7 != null && connector8 != null)
				{
					double num;
					if (flag)
					{
						num = connector7.CoordinateSystem.BasisZ.AngleOnPlaneTo(-connector3.CoordinateSystem.BasisZ, XYZ.BasisZ);
					}
					else
					{
						num = connector5.CoordinateSystem.BasisZ.AngleOnPlaneTo(-connector.CoordinateSystem.BasisZ, XYZ.BasisZ);
					}
					Line line = Line.CreateBound(this, this + XYZ.BasisZ * 10.0);
					ElementTransformUtils.RotateElement(doc, familyInstance.Id, line, num);
					connector.Origin = connector5.Origin;
					connector2.Origin = connector6.Origin;
					connector3.Origin = connector7.Origin;
					connector4.Origin = connector8.Origin;
					connector.ConnectTo(connector5);
					connector2.ConnectTo(connector6);
					connector3.ConnectTo(connector7);
					connector4.ConnectTo(connector8);
				}
				else
				{
					doc.Delete(familyInstance.Id);
				}
			}
			return familyInstance;
		}

		private double m_dParam;

		private List<Conduit> m_lstConduits;
	}
}
